package org.dreamwork.tools.swing;

import org.dreamwork.tools.ApplicationShell;
import org.dreamwork.tools.LocalUtil;
import org.dreamwork.tools.UpdateManager;
import org.dreamwork.tools.concurrent.IReceiver;
import org.dreamwork.tools.concurrent.Message;
import org.dreamwork.tools.concurrent.SimpleBroadcaster;

import javax.swing.*;
import java.awt.*;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.IOException;

/**
 * Created by seth.yang on 2018/12/12
 */
public class UpdateChecker extends JWindow implements IReceiver {
    public static void main (String[] args) throws Exception {
        UIManager.setLookAndFeel (UIManager.getSystemLookAndFeelClassName ());
        new UpdateChecker ();
    }

    private JLabel hint, index, file, speed;
    private JProgressBar bar;

    public UpdateChecker () {
        guiSetup ();
    }

    private void guiSetup () {
        JPanel root = (JPanel) getContentPane ();
        root.setBorder (BorderFactory.createEmptyBorder (10, 10, 10, 10));
        root.setLayout (new BorderLayout ());
        root.setBackground (Color.white);

        hint = createLabel ("checking update...");
        index = createLabel ("1/4");
        JPanel panel = createPanel ();
        panel.add (hint, BorderLayout.CENTER);
        panel.add (index, BorderLayout.EAST);
        root.add (panel, BorderLayout.NORTH);

        JPanel center = new JPanel (new BorderLayout ());

        panel = createPanel ();
        file = createLabel ("dreamwork-base-2.4.1.jar");
        speed = createLabel ("10.3MB/s");
        panel.add (file, BorderLayout.CENTER);
        panel.add (speed, BorderLayout.EAST);
        center.add (panel, BorderLayout.NORTH);

        panel = createPanel ();
        bar = new JProgressBar (0, 100);
        bar.setValue (56);
        panel.add (bar, BorderLayout.CENTER);
        center.add (panel, BorderLayout.CENTER);
        root.add (center, BorderLayout.CENTER);

        panel = createPanel ();
        JCheckBox box = new JCheckBox ("Run in background");
        box.setBackground (Color.white);
        JButton cancel = new JButton ("Cancel");
        cancel.addActionListener (e -> super.dispose ());
        panel.add (box, BorderLayout.CENTER);
        panel.add (cancel, BorderLayout.EAST);
        root.add (panel, BorderLayout.SOUTH);

        pack ();
        setAlwaysOnTop (true);
        setVisible (true);


        Dimension d = getSize (), D = Toolkit.getDefaultToolkit ().getScreenSize ();
        setSize (d.width * 2, d.height);
        int x = (D.width - d.width - d.width) / 2, y = (D.height - d.height) / 2;
        setLocation (x, y);

        addWindowListener (new WindowAdapter () {
            @Override
            public void windowOpened (WindowEvent e) {
                SimpleBroadcaster.getInstance ().register (UpdateManager.BC_CAT_UPDATE, UpdateChecker.this);
            }

            @Override
            public void windowClosed (WindowEvent e) {
                SimpleBroadcaster.getInstance ().unregister (UpdateManager.BC_CAT_UPDATE, UpdateChecker.this);
            }
        });
    }

    private JPanel createPanel () {
        JPanel panel = new JPanel (new BorderLayout ());
        panel.setBorder (BorderFactory.createEmptyBorder (5, 10, 5, 10));
        panel.setBackground (Color.white);
        return panel;
    }

    private JLabel createLabel (String text) {
        JLabel label = new JLabel (text);
        label.setBackground (Color.white);
        return label;
    }

    @Override
    public void received (Message message) {
        switch (message.what) {
            case UpdateManager.CODE_PROGRESS: {
                Integer count = message.get ("count");
                Integer index = message.get ("index");
                String  name  = message.get ("name");
                setUI (
                        LocalUtil.ui.getString ("label.update.processing"),
                        index + "/" + count,
                        name, null, 0
                );
                break;
            }
            case UpdateManager.CODE_DOWNLOADING: {
                String speed  = message.get ("speed");
                String name   = message.get ("name");
                Integer count = message.get ("count");
                Integer index = message.get ("index");
                Long total    = message.get ("content-length");
                Long size     = message.get ("size");

                if (count == null) count = 0;
                if (index == null) index = 0;
                if (total == null) total = 0L;
                if (size == null) size = 0L;

                setUI (
                        LocalUtil.ui.getString ("label.update.downloading"),
                        index + "/" + count,
                        name, String.valueOf (speed),
                        (double) size / total
                );
                break;
            }
            case UpdateManager.CODE_COMPLETE:
                dispose ();
                JOptionPane.showMessageDialog (null, "Update Completed\r\nThe application will restart", null, JOptionPane.INFORMATION_MESSAGE);
                try {
                    ApplicationShell.launch ();
                } catch (Exception ex) {
                    ex.printStackTrace ();
                }
                break;
            case UpdateManager.CODE_EXCEPTION:
                Exception ex = (Exception) message.arg;
                ex.printStackTrace ();
                break;
        }
    }

    private void setUI (String action, String index, String name, String downloadSpeed, double percent) {
        SwingUtilities.invokeLater (()->{
            hint.setText (action == null ? "" : action);
            this.index.setText (index == null ? "" : index);
            file.setText (name == null ? "" : name);
            speed.setText (downloadSpeed == null ? "" : downloadSpeed);
            bar.setValue ((int) (percent * 100));
        });
    }
}